/*-
 * PI.java          Parameter-Indicator (TP-PI)
 *
 * $LastChangedBy: stein $
 * $LastChangedRevision: 95 $
 * $LastChangedDate: 2007-02-13 16:19:24 +0000 (Tue, 13 Feb 2007) $
 * $HeadURL: svn://localhost/SMS/src/com/googlecode/attention/sms/pdu/PI.java $
 *
 * Copyright (c) 2007, Stein Gunnar Bakkeby
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Stein Gunnar Bakkeby nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.googlecode.attention.sms.pdu;

import com.googlecode.attention.util.IntValue;

import static com.googlecode.attention.util.bit.ByteBitValues.*;

/**
 * TP-Parameter-Indicator (TP-PI). <BR>
 * <BR>
 * The TP-Parameter-Indicator comprises a number of octets between 1 and n where
 * each bit when set to a 1 indicates that a particular optional parameter is
 * present in the fields which follow. The TP-PI is present as part of the
 * RP-User-Data in the RP-ACK, the RP-ERROR, or the RP-DATA. <BR>
 * <BR>
 * The structure of the TP-PI is as follows: <BR>
 * <BR>
 * Octet 1: <BR>
 * bit 7 - Extension bit <BR>
 * bit 6 - Reserved <BR>
 * bit 5 - Reserved <BR>
 * bit 4 - Reserved <BR>
 * bit 3 - Reserved <BR>
 * bit 2 - TP-UDL <BR>
 * bit 1 - TP-DCS <BR>
 * bit 0 - TP-PID <BR>
 * <BR>
 * The most significant bit in octet 1 and any other TP-PI octets which may be
 * added later is reserved as an extension bit which when set to a 1 shall
 * indicate that another TP-PI octet follows immediately afterwards. <BR>
 * <BR>
 * If the TP-UDL bit is set to zero then by definition neither the TP-UDL field
 * or the TP-UD field can be present. If the TP-UDL bit is set to '1' but the
 * TP-DCS bit is set to '0' then the receiving entity shall for TP-DCS assume a
 * value of 0x00, i.e. the 7bit default alphabet. <BR>
 * <BR>
 * If a Reserved bit is set to "1" then the receiving entity shall ignore the
 * setting. The setting of this bit shall mean that additional information will
 * follow the TP-User-Data, so a receiving entity shall discard any octets
 * following the TP-User-Data.
 * 
 * @author Stein Gunnar Bakkeby
 */
public class PI extends IntValue {

  /** Inherited constructor from IntValue. */
  public PI() {
    super(0);
  }

  /**
   * Inherited constructor from IntValue.
   * 
   * @param value The value of this object
   */
  public PI(final int value) {
    super(value);
  }

  /**
   * Inherited constructor from IntValue.
   * 
   * @param hex The value of this object in hex
   */
  public PI(final String hex) {
    super(hex);
  }

  /**
   * Method to check whether a PID octet is indicated.
   * 
   * @return True if PID is indicated, false otherwise
   */
  public boolean isPIDIndicated() {
    return (value & B0) != 0;
  }

  /**
   * This will set the PI to indicate that a PID octet is present.
   * 
   * @param bool True if PID octet is present, false otherwise
   */
  public void setPIDIndicated(final boolean bool) {
    if (!bool) {
      value &= N0; // B0
    } else {
      value |= B0; // B0
    }
  }

  /**
   * Method to check whether a DCS octet is indicated.
   * 
   * @return True if DCS is indicated, false otherwise
   */
  public boolean isDCSIndicated() {
    return (value & B1) != 0; // B1
  }

  /**
   * This will set the PI to indicate that a DCS octet is present.
   * 
   * @param bool True if DCS octet is present, false otherwise
   */
  public void setDCSIndicated(final boolean bool) {
    if (!bool) {
      value &= N1; // B1
    } else {
      value |= B1; // B1
    }
  }

  /**
   * Method to check whether a UDL octet is indicated.
   * 
   * @return True if UDL is indicated, false otherwise
   */
  public boolean isUDLIndicated() {
    return (value & B2) != 0;
  }

  /**
   * This will set the PI to indicate that a UDL octet is present. <BR>
   * Note that the UDL octet indicates whether a UD field is present.
   * 
   * @param bool True if UDL octet is present, false otherwise
   */
  public void setUDLIndicated(final boolean bool) {
    if (!bool) {
      value &= N2; // B2
    } else {
      value |= B2; // B2
    }
  }

  /**
   * Method to check whether there is an extension octet to this PI.
   * 
   * @return True if there is an extension octet, false otherwise
   */
  public boolean isExtensionOctetIndicated() {
    return (value & B7) != 0; // B7
  }

  /**
   * This will set the PI to indicate that an extension octet to this PI is
   * present.
   * 
   * @param bool True if an extension octet is present, false otherwise
   */
  public void setExtensionOctetIndicated(final boolean bool) {
    if (!bool) {
      value &= N7; // B7
    } else {
      value |= B7; // B7
    }
  }

  /**
   * The special case where any of the reserved bits are set to '1', then the
   * receiver should ignore any octets following the User-Data field.
   * 
   * @return True if any of the reserved bits are set to '1', false otherwise
   */
  public boolean isReservedIndicated() {
    return (value & 0x78) != 0; // 0x78 = (B6|B5|B4|B3)
  }

  /**
   * This will set the PI value.
   * 
   * @param value Integer in the range of 0 - 255, will be masked by 0xFF.
   */
  public void setValue(final int value) {
    this.value = value & ALL;
  }
}